<template>
  <el-dialog
    :title="configData.title + configData.afterTitle"
    v-model="configData.open"
    width="800px"
    :close-on-click-modal="false"
    append-to-body
    destroy-on-close
    @close="handleClose"
    class="edit-data-dialog"
  >
    <div class="dialog-container">
      <el-form
        :model="dataContainer.form"
        ref="FormElRef"
        :inline="true"
        :rules="dataContainer.rules"
        label-width="100px"
      >
        <el-row :gutter="0">
          <el-col :span="12" :xs="6">
            <el-form-item label="订单号" prop="orderNumber">
              <el-input
                v-model="dataContainer.form.orderNumber"
                placeholder="订单号"
                :disabled="true"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="租期" prop="rentalDays">
              <el-input-number
                v-model="dataContainer.form.rentalDays"
                placeholder="租期天数"
                :disabled="configData.isShow"
                :min="1"
                :max="365"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="用户姓名" prop="userId.username">
              <el-input
                v-model="dataContainer.form.userId.username"
                placeholder="用户姓名"
                :disabled="true"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="用户电话" prop="userId.phone">
              <el-input
                v-model="dataContainer.form.userId.phone"
                placeholder="用户电话"
                :disabled="true"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="车辆品牌" prop="carId.brand">
              <el-input
                v-model="dataContainer.form.carId.brand"
                placeholder="车辆品牌"
                :disabled="true"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="车辆型号" prop="carId.model">
              <el-input
                v-model="dataContainer.form.carId.model"
                placeholder="车辆型号"
                :disabled="true"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="订单状态" prop="status">
              <el-select
                v-model="dataContainer.form.status"
                placeholder="请选择订单状态"
                :disabled="configData.isShow"
                clearable
              >
                <el-option label="待支付" value="待支付" />
                <el-option label="已支付" value="已支付" />
                <el-option label="进行中" value="进行中" />
                <el-option label="已完成" value="已完成" />
                <el-option label="已取消" value="已取消" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="总金额" prop="totalAmount">
              <el-input
                v-model="dataContainer.form.totalAmount"
                placeholder="总金额"
                :disabled="configData.isShow"
                clearable
              >
                <template #prefix>¥</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="租金" prop="rentalFee">
              <el-input
                v-model="dataContainer.form.rentalFee"
                placeholder="租金"
                :disabled="configData.isShow"
                clearable
              >
                <template #prefix>¥</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="保险费" prop="insuranceFee">
              <el-input
                v-model="dataContainer.form.insuranceFee"
                placeholder="保险费"
                :disabled="configData.isShow"
                clearable
              >
                <template #prefix>¥</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="押金" prop="deposit">
              <el-input
                v-model="dataContainer.form.deposit"
                placeholder="押金"
                :disabled="configData.isShow"
                clearable
              >
                <template #prefix>¥</template>
              </el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="开始时间" prop="startTime">
              <el-date-picker
                v-model="dataContainer.form.startTime"
                type="datetime"
                placeholder="选择开始时间"
                :disabled="configData.isShow"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"
                :shortcuts="dateShortcuts"
                :disabledDate="disabledStartDate"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="结束时间" prop="endTime">
              <el-date-picker
                v-model="dataContainer.form.endTime"
                type="datetime"
                placeholder="选择结束时间"
                :disabled="configData.isShow"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"
                :shortcuts="dateShortcuts"
                :disabledDate="disabledEndDate"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="取车地点" prop="pickupLocation">
              <el-input
                v-model="dataContainer.form.pickupLocation"
                placeholder="取车地点"
                :disabled="configData.isShow"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="12" :xs="6">
            <el-form-item label="还车地点" prop="returnLocation">
              <el-input
                v-model="dataContainer.form.returnLocation"
                placeholder="还车地点"
                :disabled="configData.isShow"
                clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <template #footer>
      <div class="dialog-footer">
        <el-button
          @click="
            () => {
              dataContainer.closeType = 'cancel';
              configData.open = false;
            }
          "
        >
          取消
        </el-button>
        <el-button
          v-if="!configData.isShow"
          type="primary"
          @click="handleSubmit"
        >
          提交
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script>
/**
 * 订单数据编辑对话框
 * 使用外部调用的方式向内部传递数据
 * 使用promise的形式向外部通知状态
 */
import {
  defineComponent,
  ref,
  getCurrentInstance,
  reactive,
  nextTick,
} from "vue";
import { mergeObjProperty } from "@/common/OtherTools";
import { getDictItem, initDataByConfig } from "@/common/OtherTools";
import { verifiedData } from "@/common/VerifiedTools";
import { messageError, messageSuccess } from "@/action/MessagePrompt.js";
import ordersApi from "@/http/orders.js";

//配置信息，初始化时使用
const configMap = {
  open: {
    default: false,
  },
  title: {
    default: "订单数据",
  },
  afterTitle: {
    default: "",
  },
  isShow: {
    //是否只是展示
    default: false,
  },
};

export default defineComponent({
  name: "EditDataDialog",
  components: {},
  setup() {
    const configData = reactive({});
    const FormElRef = ref(null); //组件实例
    const dataContainer = reactive({
      loading: false,
      closeType: "close", //关闭时的类型，是由确认取消按钮关闭的还是其他地方关闭的 confirm cancel
      resolve: undefined, //返给外部promise的回调
      reject: undefined,
      form: {
        userId: {},
        carId: {},
      },
      rules: {
        status: [
          { required: true, message: "请选择订单状态", trigger: "change" },
        ],
        totalAmount: [
          { required: true, message: "请输入总金额", trigger: "blur" },
        ],
        startTime: [
          { required: true, message: "请选择开始时间", trigger: "change" },
          { validator: validateStartTime, trigger: "change" },
        ],
        endTime: [
          { required: true, message: "请选择结束时间", trigger: "change" },
          { validator: validateEndTime, trigger: "change" },
        ],
      },
    });

    // 日期快捷选项
    const dateShortcuts = [
      {
        text: "今天",
        value: new Date(),
      },
      {
        text: "明天",
        value: () => {
          const date = new Date();
          date.setTime(date.getTime() + 3600 * 1000 * 24);
          return date;
        },
      },
      {
        text: "一周后",
        value: () => {
          const date = new Date();
          date.setTime(date.getTime() + 3600 * 1000 * 24 * 7);
          return date;
        },
      },
    ];

    // 开始时间不能晚于结束时间
    function disabledStartDate(time) {
      if (!dataContainer.form.endTime) return false;
      return time.getTime() > new Date(dataContainer.form.endTime).getTime();
    }

    // 结束时间不能早于开始时间
    function disabledEndDate(time) {
      if (!dataContainer.form.startTime) return false;
      return time.getTime() < new Date(dataContainer.form.startTime).getTime();
    }

    // 校验开始时间
    function validateStartTime(rule, value, callback) {
      if (value && dataContainer.form.endTime) {
        const startDate = new Date(value);
        const endDate = new Date(dataContainer.form.endTime);
        if (startDate.getTime() > endDate.getTime()) {
          callback(new Error("开始时间不能晚于结束时间"));
        } else {
          // 更新租期
          updateRentalDays();
          callback();
        }
      } else {
        callback();
      }
    }

    // 校验结束时间
    function validateEndTime(rule, value, callback) {
      if (value && dataContainer.form.startTime) {
        const startDate = new Date(dataContainer.form.startTime);
        const endDate = new Date(value);
        if (startDate.getTime() > endDate.getTime()) {
          callback(new Error("结束时间不能早于开始时间"));
        } else {
          // 更新租期
          updateRentalDays();
          callback();
        }
      } else {
        callback();
      }
    }

    // 更新租期天数
    function updateRentalDays() {
      if (dataContainer.form.startTime && dataContainer.form.endTime) {
        const startDate = new Date(dataContainer.form.startTime);
        const endDate = new Date(dataContainer.form.endTime);
        const diffTime = Math.abs(endDate - startDate);
        const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
        dataContainer.form.rentalDays = diffDays;
      }
    }

    const otherDataContainer = {
      castParams: {}, //向外部传递的参数
    };
    initDataByConfig(configData, {}, configMap);
    /**
     * 对话框关闭时的回调
     * 根据行为类型来判断调用那个回调函数
     *  */
    function handleClose() {
      if (dataContainer.closeType == "confirm") {
        dataContainer.resolve(otherDataContainer.castParams);
      } else {
        dataContainer.reject(
          dataContainer.closeType,
          otherDataContainer.castParams
        );
      }
    }
    /**
     * 提交数据
     */
    function handleSubmit() {
      FormElRef.value.validate((valid) => {
        if (valid) {
          dataContainer.loading = true;
          const formData = { ...dataContainer.form };

          // 准备提交的数据
          const submitData = {
            status: formData.status,
            startTime: formData.startTime,
            endTime: formData.endTime,
            pickupLocation: formData.pickupLocation,
            returnLocation: formData.returnLocation,
            totalAmount: formData.totalAmount,
            rentalFee: formData.rentalFee,
            insuranceFee: formData.insuranceFee,
            deposit: formData.deposit,
            rentalDays: formData.rentalDays,
          };

          // 更新订单
          ordersApi
            .updateOrder(formData._id, submitData)
            .then((res) => {
              messageSuccess("提交成功");
              dataContainer.closeType = "confirm";
              otherDataContainer.castParams = res.data;
              configData.open = false;
            })
            .catch((err) => {
              console.error("提交失败", err);
            })
            .finally(() => {
              dataContainer.loading = false;
            });
        } else {
          return false;
        }
      });
    }
    /**
     * 外部调用的方法，初始化dialog,返回dialog的完成/取消后的状态
     * @param {*} open 是否开启dialog
     * @param {*} data 内部数据
     * @param {*} config 配置信息
     * @returns {Promise} 返回promise
     */
    function initData(open, data, config) {
      return new Promise((resolve, reject) => {
        dataContainer.resolve = resolve;
        dataContainer.reject = reject;
        configData.open = open;
        // 确保userId和carId是对象
        const formData = {
          ...data,
          userId: data.userId || {},
          carId: data.carId || {},
        };
        dataContainer.form = formData;
        mergeObjProperty(configData, config);
        dataContainer.closeType = "close";
      });
    }
    return {
      dataContainer,
      configData,
      FormElRef,
      handleClose,
      handleSubmit,
      initData,
      dateShortcuts,
      disabledStartDate,
      disabledEndDate,
    };
  },
});
</script>

<style lang="scss" scoped>
.edit-data-dialog {
  :deep(.el-dialog__header) {
    margin-right: 0px;
    padding: 10px;
    border-bottom: 1px solid var(--el-border-color-lighter);
  }
  :deep(.el-dialog__body) {
    padding: 10px;
  }
  :deep(.el-dialog__footer) {
    padding: 10px;
    border-top: 1px solid var(--el-border-color-lighter);
  }
  .dialog-container {
    padding: 10px 30px;
    min-height: 200px;
    max-height: 60vh;
    overflow-y: auto;
    .el-form-item {
      width: 100%;
      margin-bottom: 18px;
      .el-select {
        width: 100%;
      }
      .el-date-editor {
        width: 100%;
      }
    }
  }
  .dialog-footer {
    button {
      padding: 8px 20px;
    }
    > *:not(:last-child) {
      margin-right: 10px;
    }
  }
}
</style>
